package com.yanx.common.core.command;

import cn.hutool.extra.spring.SpringUtil;
import com.yanx.common.command.Executor;
import com.yanx.common.core.domain.entity.BaseEntity;
import com.yanx.common.core.domain.entity.IBaseEntity;
import com.yanx.common.core.domain.manager.BaseManager;
import com.yanx.common.core.domain.repository.BaseRepository;
import com.yanx.common.core.dto.BaseDto;
import com.yanx.common.core.vo.IdVo;
import com.yanx.common.utils.String_;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

/**
 * 增删改命令基类
 *
 * @author gotanks
 * @date 2021-04-19 18:40:00
 */
@Setter
@Getter
public abstract class CrudCommand<DTO extends BaseDto> extends DomainCommand<IdVo> {

    private Serializable id;

    private Collection ids;

    private DTO dto;

    /**
     * 新建操作构造方法
     *
     * @param dto
     */
    public CrudCommand(DTO dto) {
        this(dto.getId(), dto);
    }

    /**
     * 更新操作构造方法
     *
     * @param id
     * @param dto
     */
    public <ID extends Serializable> CrudCommand(ID id, DTO dto) {
        this.id = id;
        this.dto = dto;
    }

    /**
     * 删除操作构造方法
     *
     * @param id
     */
    public <ID extends Serializable> CrudCommand(ID id) {
        this.id = id;
    }

    /**
     * 批量删除操作构造方法
     *
     * @param ids
     */
    public <ID extends Serializable> CrudCommand(Collection<ID> ids) {
        this.ids = ids;
    }

    @Override
    public IdVo execute(Executor executor) {
        String receiverName = receiverName();
        Class<? extends BaseManager> mClazz = receiverClass(receiverName);
        BaseManager<? extends BaseEntity, ? extends BaseRepository> receiver = executor.getReceiver(mClazz);
        return this.handler(receiver);
    }

    public <E extends BaseEntity, R extends BaseRepository> IdVo handler(BaseManager<E, R> receiver) {
        if (ids != null) {
            //批量删除
            receiver.remove(ids);
        } else if (id == null && dto != null) {
            //新增
            IBaseEntity entity = receiver.save(toEntity());
            return IdVo.of(entity.getId());
        } else if (id != null && dto != null) {
            //修改
            receiver.update(id, t -> toEntity(t));
            return IdVo.of(id);
        } else if (id != null && dto == null) {
            //删除
            receiver.remove(id);
            return IdVo.of(id);
        }
        return null;
    }

    public <E extends BaseEntity> E toEntity() {
        return null;
    }

    public <E extends BaseEntity> E toEntity(E entity) {
        return entity;
    }

    protected Class<? extends BaseManager> receiverClass(String receiverName) {
        Map<String, BaseManager> beansOfType = SpringUtil.getBeansOfType(BaseManager.class);
        Class<? extends BaseManager> managerClazz = null;
        for (Map.Entry<String, BaseManager> entry : beansOfType.entrySet()) {
            managerClazz = entry.getValue().getClass();
            if (entry.getKey().equals(String_.lowerFirst(receiverName)) || entry.getKey().equals(receiverName)) {
                break;
            }
        }
        return managerClazz;
    }

    protected String receiverName() {
        return this.getClass().getSimpleName()
                .replace("Cmd", "")
                .replace("Create", "")
                .replace("Update", "")
                .replace("Delete", "")
                + "Manager";
    }

}
